#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QMessageBox>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <QDir>
#include <QThread>
#include "mytcpsocket.h"
#include "noticeitem.h"


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);


    //初始化
    init();
    // 日志拦截 自行处理
    //initLogger();
    //客户端总控函数
    mainControl();



}

Widget::~Widget()
{
    delete ui;
}

void Widget::init()
{
    // 设置窗口图标
    this->setWindowIcon(QIcon(":/prefix2/software/dragon_ico.ico"));
    // 登录窗口的初始化
    m_login = new LoginWindow();
    // 主界面的初始化
    m_main = new MainUI();
    // 全局socket 读缓冲可读的消息 传给主控程序处理
    connect(GlobalObject::getGlobalObject()->getTcpsocket(),SIGNAL(jsonRecv(QString)),this,SLOT(dealReply(QString)));
    // 登录成功
    connect(m_login,&LoginWindow::login_success,this,[=]{
        //进入主界面
        m_main->show();
        // gif线程退出
        m_login->getT1()->quit();  // 请求线程停止
        m_login->getT1()->wait();  // 等待线程停止
        delete m_login->getT1();    // gif线程没有指定父对象,手动释放内存

        //关闭登录界面
        m_login->close();

        struct st_notice notice(WELCOME);
        QVariant var;
        var.setValue(notice);
        emit m_main->getNoticeWindow()->sign_addNotice(var);
    });
    // 清空临时目录tmp下的文件
    clearTmpFile();

    //连接服务器
    GlobalObject::getGlobalObject()->getTcpsocket()->connectToHost(QHostAddress(SRV_ADDR),SRV_PORT);

    qDebug()<<"maincontrol init success";

}

void Widget::initLogger()
{
    /*
        qInstallMessageHandler()是一个回调函数，它允许我们拦截应用程序产生的日志消息，并由我们自己处理它
    */
    // 设置全局的日志输出格式
    qInstallMessageHandler([](QtMsgType type, const QMessageLogContext &context, const QString &msg) {
        QByteArray localMsg;
        switch (type) {
        case QtDebugMsg:
            localMsg = "[Debug] ";
            break;
        case QtWarningMsg:
            localMsg = "[Warning] ";
            break;
        case QtCriticalMsg:
            localMsg = "[Critical] ";
            break;
        case QtFatalMsg:
            localMsg = "[Fatal] ";
            break;
        }
        QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        QString message = QString("(%1): %2").arg(current_date_time).arg(msg);

        localMsg.append(message.toUtf8());

        QFile file("../log/log.txt");
        file.open(QIODevice::WriteOnly | QIODevice::Append);
        QTextStream text_stream(&file);
        text_stream << localMsg<<"\n";
        file.flush();
        file.close();
    });

    // 以后就可以像下面这样直接打日志到文件中，而且日志也会包含时间信息
    //qDebug( "This is a debug message at thisisqt.com ");
    //qWarning( " This is a warning message  at thisisqt.com " );
    //qCritical( " This is a critical message  at thisisqt.com " );  严重、危险错误
    //qFatal( " This is a fatal message at thisisqt.com " );     致命错误，这个日志级别的消息打印会使程序崩溃
}

void Widget::mainControl()
{
    m_login->show();
}

QString Widget::analysisJsonReply(QByteArray json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json);
    QString cmd;    //命令类型
    if(doc.isObject())
    {
        QJsonObject obj = doc.object();//转换为json对象
        QStringList keys = obj.keys(); //获取所有的键值
        //确定命令类型
        for(int i=0; i<keys.size(); ++i)
        {
            QString key = keys.at(i);
            QJsonValue val = obj.value(key);
            if(key == "cmd"){
                cmd = val.toString();
                break;
            }
        }
    }
    return cmd;
}

void Widget::dealLoginReply(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());  //json文档对象
    struct st_userInfo userInfo;    //用户信息结构体
    QJsonObject obj = doc.object(); //转换为json对象
    QString result = obj["result"].toString(); //响应结果
    if(result == "error"){      // 接收到error回复,登录失败
        emit m_login->rejected();
        return;
    }
    else if(result == "already_login"){// 已登录,不能重复登录
        emit m_login->finished(2);
        return;
    }
    userInfo.sdata.dd_num = obj["user"][0]["dd_num"].toInt();
    userInfo.sdata.pwd = obj["user"][0]["pwd"].toString();
    userInfo.sdata.nick = obj["user"][0]["nick"].toString();
    userInfo.sdata.sex = obj["user"][0]["sex"].toString();
    userInfo.sdata.phone = obj["user"][0]["phone"].toString();
    userInfo.sdata.email = obj["user"][0]["email"].toString();
    userInfo.sdata.city = obj["user"][0]["city"].toString();
    userInfo.sdata.gxqm = obj["user"][0]["gxqm"].toString();
    userInfo.sdata.birthday = obj["user"][0]["birthday"].toString();
    userInfo.sdata.status = obj["user"][0]["status"].toInt();

    QJsonArray arrObj = obj["friends"].toArray();
    for(int i = 0;i<arrObj.size();i++){ //遍历json数组
        struct st_friendData fdata; //好友的个人资料
        fdata.dd_num = arrObj[i].toObject()["dd_num"].toInt();
        fdata.nick = arrObj[i].toObject()["nick"].toString();
        fdata.sex = arrObj[i].toObject()["sex"].toString();
        fdata.phone = arrObj[i].toObject()["phone"].toString();
        fdata.email = arrObj[i].toObject()["email"].toString();
        fdata.city = arrObj[i].toObject()["city"].toString();
        fdata.gxqm = arrObj[i].toObject()["gxqm"].toString();
        fdata.birthday = arrObj[i].toObject()["birthday"].toString();
        fdata.status = arrObj[i].toObject()["status"].toInt();
        userInfo.friend_list.append(fdata);
    }

    QJsonArray arrObj2 = obj["groups"].toArray();

    for(int i = 0;i<arrObj2.size();i++){ //遍历json数组
        struct st_gData gdata; //群资料
        gdata.gid = arrObj2[i].toObject()["gid"].toInt();
        gdata.gname = arrObj2[i].toObject()["gname"].toString();
        gdata.gboss = arrObj2[i].toObject()["gboss"].toInt();
        gdata.gintroduce = arrObj2[i].toObject()["gintroduce"].toString();
        userInfo.group_list.append(gdata);
    }

//    QJsonArray arrObj3 = arrObj2[i].toObject()["gmembers"].toArray();
//    struct st_gMemberData gmdata;
//    for(int j = 0;j<arrObj3.size();j++){
//        gmdata.mid = arrObj3[j].toObject()["mid"].toInt();
//        gmdata.nick = arrObj3[j].toObject()["nick"].toString();
//        gdata.gmembers.push_back(gmdata);
//    }


//    QString result; //响应结果
//    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());  //json文档对象
//    struct st_userInfo userInfo;    //用户信息结构体
//    QJsonObject obj = doc.object(); //转换为json对象
//    QStringList keys = obj.keys();  //获取所有的键值
//    for(int i=0; i<keys.size(); ++i){
//        QString key = keys.at(i);
//        QJsonValue val = obj.value(key);
//        if(key == "result"){
//            result = val.toString();
//            if(result == "error"){      // 接收到error回复,登录失败
//                emit m_login->rejected();
//                return;
//            }
//            if(result == "already_login"){// 已登录,不能重复登录
//                emit m_login->finished(2);
//                return;
//            }
//        }
//        else if(key == "user"){  //个人资料
//            QJsonArray arrObj = val.toArray();
//            QJsonObject obj2 = arrObj.first().toObject();   //个人资料的json数组里只有1个json对象
//            QStringList keys2 = obj2.keys();   //获取json对象里的所有键值对
//            for(int j = 0;j<keys2.size();j++){
//                QString key2 = keys2.at(j);
//                QJsonValue val2 = obj2.value(key2);
//                if(key2 == "dd_num")
//                    userInfo.sdata.dd_num = val2.toInt();
//                else if(key2 == "pwd")
//                    userInfo.sdata.pwd = val2.toString();
//                else if(key2 == "nick")
//                    userInfo.sdata.nick = val2.toString();
//                else if(key2 == "sex")
//                    userInfo.sdata.sex = val2.toString();
//                else if(key2 == "phone")
//                    userInfo.sdata.phone = val2.toString();
//                else if(key2 == "email")
//                    userInfo.sdata.email = val2.toString();
//                else if(key2 == "city")
//                    userInfo.sdata.city = val2.toString();
//                else if(key2 == "gxqm")
//                    userInfo.sdata.gxqm = val2.toString();
//                else if(key2 == "birthday")
//                    userInfo.sdata.birthday = val2.toString();
//                else if(key2 == "status")
//                    userInfo.sdata.status = val2.toInt();
//            }
//        }
//        else if(key == "friends"){   //好友列表
//            QJsonArray arrObj = val.toArray();  //有多个json对象
//            for(int i = 0;i<arrObj.size();i++){ //遍历json数组
//                QJsonObject obj2 = arrObj[i].toObject();  //得到json对象
//                QStringList keys2 = obj2.keys();   //获取json对象里的所有键值对
//                struct st_friendData fdata; //好友的个人资料
//                for(int j = 0;j<keys2.size();j++){
//                    QString key2 = keys2.at(j);
//                    QJsonValue val2 = obj2.value(key2);
//                    if(key2 == "dd_num")
//                        fdata.dd_num = val2.toInt();
//                    else if(key2 == "nick")
//                        fdata.nick = val2.toString();
//                    else if(key2 == "sex")
//                        fdata.sex = val2.toString();
//                    else if(key2 == "status")
//                        fdata.status = val2.toInt();
//                }
//                userInfo.friend_list.append(fdata);
//            }
//        }
//        else if(key == "groups"){    // 群列表
//            QJsonArray arrObj = val.toArray();  //有多个json对象
//            for(int i = 0;i<arrObj.size();i++){ //遍历json数组
//                QJsonObject obj2 = arrObj[i].toObject();  //得到json对象
//                QStringList keys2 = obj2.keys();   //获取json对象里的所有键值对
//                struct st_gData gdata; // 群资料
//                for(int j = 0;j<keys2.size();j++){
//                    QString key2 = keys2.at(j);
//                    QJsonValue val2 = obj2.value(key2);
//                    if(key2 == "gid")
//                        gdata.gid = val2.toInt();
//                    else if(key2 == "gname")
//                        gdata.gname = val2.toString();
//                    else if(key2 == "gboss")
//                        gdata.gboss = val2.toInt();
//                    else if(key2 == "gintroduce")
//                        gdata.gintroduce = val2.toString();
//                    else if(key2 == "gmembers"){
//                        QJsonArray arrObj2 = val2.toArray();
//                        for(int k = 0;k<arrObj2.size();k++){
//                            QJsonObject obj3 = arrObj2.at(k).toObject();
//                            QStringList keys3 = obj3.keys();
//                            struct st_gMemberData gmdata;
//                            for(int m = 0;m < keys3.size();m++){
//                                QString key3 = keys3.at(m);
//                                QJsonValue val3 = obj3.value(key3);
//                                if(key3 == "mid")
//                                    gmdata.mid=val3.toInt();
//                                else if(key3 == "nick")
//                                    gmdata.nick = val3.toString();
//                            }
//                            gdata.gmembers.push_back(gmdata);
//                        }
//                    }
//                }
//                userInfo.group_list.append(gdata);
//            }
//        }

//    }
    GlobalObject::getGlobalObject()->setUserInfo(userInfo);

    emit m_main->login_success();   //传递用户信息到主界面
    emit m_login->accepted();       //通知主控程序 登录成功
}

void Widget::dealAddFriendRequest(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    struct st_friendData fdata; //存储的是好友的个人资料
    fdata.dd_num = obj["send"].toInt();
    fdata.nick = obj["content"].toString();

    struct st_notice notice(ADD_FRIEND_REQUEST,fdata);
    m_main->getNoticeWindow()->addNotice(notice);    //将通知添加进通知信箱

}

void Widget::dealGetUserInfoReply(const QString &json)
{
    QString result; //响应结果
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());  //json文档对象
    QJsonObject obj = doc.object();//转换为json对象
    QStringList keys = obj.keys();  //获取所有键值
    for(int i = 0;i<keys.size();i++){
        QString key = keys.at(i);   //键
        QJsonValue val = obj.value(key);    //值
        if(key == "result"){
            st_searchUserResult searchRes;  //搜索好友查询结果结构体
            if(val.isString() && val.toString() == "user_not_exist"){   //查询无结果,用户不存在
                searchRes.res = 0;  //0 无结果
            }else{
                searchRes.res = 1;  //1 有结果
                QJsonArray arrObj = val.toArray();  //有多个json对象
                for(int i = 0;i<arrObj.size();i++){ //遍历json数组
                    QJsonObject obj2 = arrObj[i].toObject();  //得到json对象
                    QStringList keys2 = obj2.keys();   //获取json对象里的所有键值对
                    struct st_friendData fdata; //存储的是好友的个人资料
                    for(int j = 0;j<keys2.size();j++){
                        QString key2 = keys2.at(j);
                        QJsonValue val2 = obj2.value(key2);
                        if(key2 == "dd_num")
                            fdata.dd_num = val2.toInt();
                        else if(key2 == "nick")
                            fdata.nick = val2.toString();
                        else if(key2 == "sex")
                            fdata.sex = val2.toString();
                    }
                    searchRes.friend_list.push_back(fdata);
                }
            }
            QVariant var;
            var.setValue(searchRes);
            emit m_main->getAddWindow()->sig_searchResult(var);
        }
    }
}

void Widget::dealAddFriendReply(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    QStringList keys = obj.keys();  //获取所有键值
    QString result;
    for(int i = 0;i<keys.size();i++){
        QString key = keys.at(i);   //键
        QJsonValue val = obj.value(key);    //值
        if(key == "result"){
            result = val.toString();
            if(result == "add_myself"){ //添加自己为好友
                QMessageBox msgbox(QMessageBox::Information,"DragonIM","不能添加自己为好友!",QMessageBox::Ok);
                msgbox.exec();
                return;
            }
            else if(result == "already_friend"){ //已经是好友
                QMessageBox msgbox(QMessageBox::Information,"DragonIM","你和对方已经是好友关系!",QMessageBox::Ok);
                msgbox.exec();
                return;
            }
            else if(result == "wait"){ //请求发送成功,等待对方处理
                QMessageBox msgbox(QMessageBox::Information,"DragonIM","请求发送成功!等待对方处理。",QMessageBox::Ok);
                msgbox.exec();
                return;
            }
        }
    }
}

void Widget::dealAddFriendResult(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    struct st_friendData fdata;      //处理方的个人资料
    QString content = obj["content"].toString();
    QStringList ml = content.split('#');
    QString result = ml.front(); //处理结果
    fdata.dd_num = obj["send"].toInt();
    fdata.nick = ml.back();

    if(result == "agree"){
        struct st_notice notice(ADD_FRIEND_RESULT,fdata,1);
        QVariant var;
        var.setValue(notice);
        emit m_main->getNoticeWindow()->sign_dealResult(var);
    }
    else if(result == "refuse"){
        struct st_notice notice(ADD_FRIEND_RESULT,fdata,0);
        QVariant var;
        var.setValue(notice);
        emit m_main->getNoticeWindow()->sign_dealResult(var);
    }
}

void Widget::dealFriendLogin(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    QStringList keys = obj.keys();
    int m_friend;   //登录的好友
    for(int i = 0;i<keys.size();i++){
        QString key = keys.at(i);
        QJsonValue val = obj.value(key);
        if(key == "friend")
            m_friend = val.toInt();
    }
    emit m_main->sign_friendStatus_change(m_friend,1);     // 1 在线  0 离线
}

void Widget::dealFriendQuit(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    QStringList keys = obj.keys();
    int m_friend;   //离线的好友
    for(int i = 0;i<keys.size();i++){
        QString key = keys.at(i);
        QJsonValue val = obj.value(key);
        if(key == "friend")
            m_friend = val.toInt();
    }
    emit m_main->sign_friendStatus_change(m_friend,0);     // 1 在线  0 离线
}

void Widget::dealDeleteFriendNotice(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    struct st_friendData udata;     //与你解除好友关系的用户
    udata.dd_num = obj["send"].toInt();
    udata.nick = obj["content"].toString();

    //更新好友链表 (删除好友)
    GlobalObject::getGlobalObject()->deleteFriendFromList(udata.dd_num);
    //更新UI界面
    emit m_main->sign_deleteFriend(udata.dd_num);
    //更新通知窗口
    struct st_notice notice(DELETE_FRIEND_NOTICE,udata);
    QVariant var;
    var.setValue(notice);
    emit m_main->getNoticeWindow()->sign_addNotice(var);
}

void Widget::dealNewPush(const QString &json)
{
    //推送通知 代表有新消息到达,向服务器发送 拉取请求
    int uid = GlobalObject::getGlobalObject()->getUserInfo().sdata.dd_num;   //自己的用户号

    QVariantMap map;
    map["cmd"] = "pull_request";
    map["timelineID"] = uid;

    //发送请求
    GlobalObject::getGlobalObject()->sendRequest(map);

    //  消息漫游时使用
    //    int sender; //发送方
    //    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    //    QJsonObject obj = doc.object();
    //    QStringList keys = obj.keys();
    //    for(int i = 0;i<keys.size();i++){
    //        QString key = keys.at(i);
    //        QJsonValue val = obj.value(key);
    //        if(key == "send"){
    //            sender = val.toInt();
    //            break;
    //        }
    //    }
    //    QString sessionID;
    //    //会话编号 UID小的在左边  双方共享一个会话TimeLine
    //    if(uid<sender)
    //        sessionID = QString("%1-%2").arg(QString::number(uid)).arg(QString::number(sender));
    //    else
    //        sessionID = QString("%1-%2").arg(QString::number(sender)).arg(QString::number(uid));

}

void Widget::dealPrivateChat(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    QStringList keys = obj.keys();
    struct st_msg msg;  //消息结构体
    for(int i = 0;i<keys.size();i++){
        QString key = keys.at(i);
        QJsonValue val = obj.value(key);
        if(key == "send")
            msg.send = val.toInt();
        else if(key == "recv")
            msg.recv = val.toInt();
        else if(key == "type")
            msg.type = val.toInt();
        else if(key == "content")
            msg.contect = val.toString();
        else if(key == "timestamp")
            msg.sendtime = val.toString();
    }

    QVariant var;
    var.setValue(msg);
    emit m_main->sign_privateChatMsg(var);

}

void Widget::dealFileHeadACK(const QString &json)
{
    QFileInfo fileinto(GlobalObject::getGlobalObject()->getSendfilePath());
    QString filename = fileinto.fileName(); // 文件名(带后缀,但不带路径)
    // 解析文件ID
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    GlobalObject::getGlobalObject()->setUploadFileID(obj["fileID"].toString());

    // 解析文件ID,求文件上传路径  取ms级时间戳的末3位
    int partitionID = GlobalObject::getGlobalObject()->getUploadFileID().right(3).toInt() % 7;  // 一共0~9的分区，对7取模
    // 记录资源在服务器上的位置(发图文动态有用到)
    GlobalObject::getGlobalObject()->setSaveFileSrvPath(QString("%1/%2/%3").arg(PATH_FILE).arg(partitionID).arg(filename));
    QString path = QString("/DragonIM/file/%1/%2").arg(partitionID).arg(filename);
    QString srvpath = QString("%1:%2").arg(SRV_HOSTNAME).arg(path);
    QString localpath = GlobalObject::getGlobalObject()->getSendfilePath();
    qDebug()<<"fileID:"<<GlobalObject::getGlobalObject()->getUploadFileID();
    qDebug()<<"localpath:"<<localpath;
    qDebug()<<"srvpath:"<<srvpath;
    // 上传文件(上传完毕需要给服务器发送文件上传完毕)
    GlobalObject::getGlobalObject()->uploadToServer(localpath,srvpath);
}



void Widget::dealUpLoadReply(const QString &json)
{
    // 解析上传结果
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    QString result = obj["result"].toString();

    // 如果上传失败，弹出消息框提示用户
    if(result == "fail"){
        QMessageBox::information(this,"错误","文件上传失败!");
        return;
    }

    int flag = GlobalObject::getGlobalObject()->getUpload_file_flag();
    // 群文件
    if(flag == 2){
        // 上传成功，向服务器发送群文件上传
        QVariantMap map;
        map["cmd"] = "upload_group_file";
        map["fid"] = GlobalObject::getGlobalObject()->getUploadFileID();            // 文件唯一标识
        map["gid"] = GlobalObject::getGlobalObject()->getCurrentSendFileGid();      // 所属群组
        map["uid"] = GlobalObject::getGlobalObject()->getUserInfo().sdata.dd_num;   // 上传者
        map["nick"] = GlobalObject::getGlobalObject()->getUserInfo().sdata.nick;   // 上传者昵称
        //发送群文件上传
        GlobalObject::getGlobalObject()->sendRequest(map);
    }
    // 私聊文件
    else if(flag == 1){
        // 上传成功，向服务器发送私聊文件
        QVariantMap map;
        map["cmd"] = "private_chat";
        map["send"] = GlobalObject::getGlobalObject()->getUserInfo().sdata.dd_num;          // 发送方
        map["recv"] = GlobalObject::getGlobalObject()->getCurrentSendFileUid();             // 接收方
        map["type"] = 52;                                                                   // 私聊文件
        map["content"] = GlobalObject::getGlobalObject()->getUploadFileID();                 // 文件ID

        // 发送私聊文件
        GlobalObject::getGlobalObject()->sendRequest(map);
    }
    // 动态图片
    else if(flag == 3){
        emit m_main->getPyqwindow()->getAddfeedwindow()->sig_announceFeed();
    }
}

void Widget::dealCreateGroupReply(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    QStringList keys = obj.keys();
    struct st_gData gdata;
    for(int i = 0;i<keys.size();i++){
        QString key = keys.at(i);
        QJsonValue val = obj.value(key);
        if(key == "gid")
            gdata.gid = val.toInt();
        else if(key == "gboss")
            gdata.gboss = val.toInt();
        else if(key == "gname")
            gdata.gname = val.toString();
        else if(key == "gintroduce")
            gdata.gintroduce = val.toString();

    }

    // 添加到群聊链表 内部封装插入方法，直接插入会失效
    GlobalObject::getGlobalObject()->insertGroupElement(gdata);

    // 更新UI界面（包括添加到群资料与窗口聊天Map）
    emit m_main->sign_addGroup(gdata.gid);

    QMessageBox::information(this,"DragonIM","创建群聊成功");

    // 关闭创建窗口
    m_main->getCreategroupwindow()->close();


}

void Widget::dealNewGroupNotice(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    struct st_gData gdata;
    QStringList ml = obj["content"].toString().split('-');
    gdata.gid = ml.front().toInt();
    gdata.gname = ml.back();
    gdata.gboss = obj["send"].toInt();

    struct st_notice notice(NEW_GROUP_NOTICE,gdata);
    QVariant var;
    var.setValue(notice);
    emit m_main->getNoticeWindow()->sign_addNotice(var);

}

void Widget::dealDissolveGroupReply(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    int gid = obj["gid"].toInt();
    emit m_main->sign_deleteGroup(gid);
    QMessageBox::information(this,"DragonIM","解散群聊成功");
}

void Widget::dealGetGroupInfoReply(const QString &json)
{
    QString result; //响应结果
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());  //json文档对象
    QJsonObject obj = doc.object();//转换为json对象
    QStringList keys = obj.keys();  //获取所有键值
    for(int i = 0;i<keys.size();i++){
        QString key = keys.at(i);   //键
        QJsonValue val = obj.value(key);    //值
        if(key == "result"){
            st_searchGroupResult searchRes;  //搜索群聊查询结果结构体
            if(val.isString() && val.toString() == "group_not_exist"){   //查询无结果,群聊不存在
                searchRes.res = 0;  //0 无结果
            }else{
                searchRes.res = 1;  //1 有结果
                QJsonArray arrObj = val.toArray();  //有多个json对象
                for(int i = 0;i<arrObj.size();i++){ //遍历json数组
                    QJsonObject obj2 = arrObj[i].toObject();  //得到json对象
                    QStringList keys2 = obj2.keys();   //获取json对象里的所有键值对
                    struct st_gData gdata; //存储的是群聊资料
                    for(int j = 0;j<keys2.size();j++){
                        QString key2 = keys2.at(j);
                        QJsonValue val2 = obj2.value(key2);
                        if(key2 == "gid")
                            gdata.gid = val2.toInt();
                        else if(key2 == "gname")
                            gdata.gname = val2.toString();
                        else if(key2 == "gboss")
                            gdata.gboss = val2.toInt();
                        else if(key2 == "gintroduce")
                            gdata.gintroduce = val2.toString();
                    }
                    searchRes.group_list.push_back(gdata);
                }
            }
            QVariant var;
            var.setValue(searchRes);
            emit m_main->getAddWindow()->sig_searchGroupResult(var);
        }
    }
}

void Widget::dealAddGroupReply(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    QString result = obj["result"].toString();
    // 已经是群成员
    if(result == "already_gmember")
    {
        QMessageBox msgbox(QMessageBox::Information,"DragonIM","你已经是该群聊成员!",QMessageBox::Ok);
        msgbox.exec();
        return;
    }
    // 群聊不存在
    else if(result == "group_not_exist")
    {
        QMessageBox msgbox(QMessageBox::Information,"DragonIM","群聊不存在!",QMessageBox::Ok);
        msgbox.exec();
        return;
    }
    // 添加成功
    else
    {
         struct st_gData gdata; //存储的是群聊资料
         gdata.gid = obj["gid"].toInt();
         gdata.gname = obj["gname"].toString();
         gdata.gboss = obj["gboss"].toInt();
         gdata.gintroduce = obj["gintroduce"].toString();
         // 群聊添加到群链表中
         GlobalObject::getGlobalObject()->insertGroupElement(gdata);
         // 更新UI界面（包括添加到群资料与窗口聊天Map）
         emit m_main->sign_addGroup(gdata.gid);
         QMessageBox::information(this,"DragonIM","加入群聊成功!",QMessageBox::Ok);
    }

}

void Widget::dealDissolveGroupNotice(const QString &json)
{
    // 用户收到解散群聊通知,解析gid
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
//    QStringList ml = obj["content"].toString().split('-');
    struct st_gData gdata;
//    gdata.gid = ml.front().toInt();
    gdata.gname = obj["content"].toString();

    // 添加通知到通知信箱
    struct st_notice notice(DISSOLVE_GROUP_NOTICE,gdata);
    QVariant var;
    var.setValue(notice);
    emit m_main->getNoticeWindow()->sign_addNotice(var);

//    // 删除群聊链表中的群聊(如果是离线拉取的用户,这一步根本执行不了,包括更新UI)
//    GlobalObject::getGlobalObject()->deleteGroupFromList(gid);
    // 更新UI(包括Map)
    emit m_main->sign_deleteGroup(gdata.gid);
}

void Widget::dealQuitGroupReply(const QString &json)
{

    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    QStringList keys = obj.keys();
    int gid;
    for(int i = 0;i<keys.size();i++){
        QString key = keys.at(i);
        QJsonValue val = obj.value(key);
        if(key == "gid")
            gid = val.toInt();
    }


    // 更新群聊链表
    GlobalObject::getGlobalObject()->deleteGroupFromList(gid);
    // 更新UI界面（包括删除群资料与窗口聊天Map）
    emit m_main->sign_deleteGroup(gid);

    QMessageBox::information(this,"DragonIM","已退出群聊!");
}

void Widget::dealCodeOutError(const QString &json)
{
    QMessageBox::information(this,"验证码错误","验证码过期或不正确!");
}

void Widget::dealPhoneAlreadyRegister(const QString &json)
{
    QMessageBox::information(this,"错误","手机号已被注册!");
}

void Widget::dealRegisterReply(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    QStringList keys = obj.keys();
    int dd_num;
    for(int i = 0;i<keys.size();i++){
        QString key = keys.at(i);
        QJsonValue val = obj.value(key);
        if(key=="dd_num")
            dd_num = val.toInt();
    }
    QString content = QString("注册成功!\n UID:%1\n").arg(QString::number(dd_num));
    QMessageBox::information(this,"消息",content);
    emit m_login->getRegister_window()->sig_gotoLogin(dd_num);
}

void Widget::dealGroupChat(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    QStringList keys = obj.keys();
    struct st_msg msg;  //消息结构体
    for(int i = 0;i<keys.size();i++){
        QString key = keys.at(i);
        QJsonValue val = obj.value(key);
        if(key == "send")
            msg.send = val.toInt();
        else if(key == "recv")
            msg.recv = val.toInt();
        else if(key == "type")
            msg.type = val.toInt();
        else if(key == "content")
            msg.contect = val.toString();
        else if(key == "timestamp")
            msg.sendtime = val.toString();
    }

    QVariant var;
    var.setValue(msg);
    emit m_main->sign_groupChatMsg(var);
}

void Widget::dealNewFeed(const QString &json)
{
    // 动态通知 代表有有好友发送了新的动态,向服务器发送 动态拉取请求
    int uid = GlobalObject::getGlobalObject()->getUserInfo().sdata.dd_num;   //自己的用户号

    QVariantMap map;
    map["cmd"] = "feed_pull_request";
    map["timelineID"] = uid;

    //发送请求
    GlobalObject::getGlobalObject()->sendRequest(map);
}

void Widget::dealFeed(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    QStringList keys = obj.keys();
    struct st_feed feed;  // 动态结构体
    for(int i = 0;i<keys.size();i++){
        QString key = keys.at(i);
        QJsonValue val = obj.value(key);
        if(key == "announcer")
            feed.announcer = val.toInt();
        else if(key == "nick")
            feed.nick = val.toString();
        else if(key == "pyqtype")
            feed.pyqtype = val.toInt();
        else if(key == "content")
            feed.content = val.toString();
        else if(key == "sendtime")
            feed.sendtime = val.toString();
        else if(key == "feedID")
            feed.feedID = val.toString();
    }

    QVariant var;
    var.setValue(feed);
    emit m_main->getPyqwindow()->sig_newFeed(var);
}

void Widget::dealNewDZPL(const QString &json)
{
    // 点赞评论通知 代表有有好友评论了 自己/自己的好友的动态
    int uid = GlobalObject::getGlobalObject()->getUserInfo().sdata.dd_num;   //自己的用户号

    QVariantMap map;
    map["cmd"] = "dzpl_pull_request";
    map["timelineID"] = uid;

    //发送请求
    GlobalObject::getGlobalObject()->sendRequest(map);
}

void Widget::dealPL(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    QStringList keys = obj.keys();
    struct st_dzpl dzpl;  // 动态结构体
    for(int i = 0;i<keys.size();i++){
        QString key = keys.at(i);
        QJsonValue val = obj.value(key);
        if(key == "uid")
            dzpl.uid = val.toInt();
        else if(key == "nick")
            dzpl.nick = val.toString();
        else if(key == "feedID")
            dzpl.feedID = val.toString();
        else if(key == "type")
            dzpl.type = val.toInt();
        else if(key == "content")
            dzpl.content = val.toString();
        else if(key == "optime")
            dzpl.optime = val.toString();
        else if(key == "opID")
            dzpl.opID = val.toString();
    }

    QVariant var;
    var.setValue(dzpl);
    emit m_main->getPyqwindow()->sig_newPL(var);
}

void Widget::dealDZ(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    QStringList keys = obj.keys();
    struct st_dzpl dzpl;  // 动态结构体
    for(int i = 0;i<keys.size();i++){
        QString key = keys.at(i);
        QJsonValue val = obj.value(key);
        if(key == "uid")
            dzpl.uid = val.toInt();
        else if(key == "nick")
            dzpl.nick = val.toString();
        else if(key == "feedID")
            dzpl.feedID = val.toString();
        else if(key == "type")
            dzpl.type = val.toInt();
        else if(key == "content")
            dzpl.content = val.toString();
        else if(key == "optime")
            dzpl.optime = val.toString();
        else if(key == "opID")
            dzpl.opID = val.toString();
    }

    QVariant var;
    var.setValue(dzpl);
    emit m_main->getPyqwindow()->sig_newDZ(var);
}

void Widget::dealUNDZ(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    QStringList keys = obj.keys();
    struct st_dzpl dzpl;  // 动态结构体
    for(int i = 0;i<keys.size();i++){
        QString key = keys.at(i);
        QJsonValue val = obj.value(key);
        if(key == "uid")
            dzpl.uid = val.toInt();
        else if(key == "nick")
            dzpl.nick = val.toString();
        else if(key == "feedID")
            dzpl.feedID = val.toString();
        else if(key == "type")
            dzpl.type = val.toInt();
        else if(key == "content")
            dzpl.content = val.toString();
        else if(key == "optime")
            dzpl.optime = val.toString();
        else if(key == "opID")
            dzpl.opID = val.toString();
    }

    QVariant var;
    var.setValue(dzpl);
    emit m_main->getPyqwindow()->sig_unDZ(var);
}

void Widget::dealNewGroupFile(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    struct st_file file;
    file.fid = obj["fid"].toString();
    file.fname = obj["fname"].toString();
    file.fsize = obj["fsize"].toInteger();
    file.fpath = obj["fpath"].toString();
    file.gid = obj["gid"].toInt();
    file.uid = obj["uid"].toInt();
    file.nick = obj["nick"].toString();
    file.upload_time = obj["upload_time"].toString();

    QVariant var;
    var.setValue(file);
    emit m_main->getMap_groupchatwindow()[file.gid]->sig_addGroupFile(var);
}

void Widget::dealFileSrvpath(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();

    // 解析资源路径
    QString path = obj["srvpath"].toString();
    QString srvpath = QString("%1:%2").arg(SRV_HOSTNAME).arg(path);
    QString localpath = GlobalObject::getGlobalObject()->getSaveFileLocalPath();

    qDebug()<<"srvpath:"<<srvpath;
    qDebug()<<"localpath:"<<localpath;

    // 下载资源
    GlobalObject::getGlobalObject()->downloadToLocal(srvpath,localpath);
}

void Widget::dealModifyUserInfoReply(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    QString result = obj["result"].toString();
    if(result == "success")
        QMessageBox::information(this,"消息","资料修改成功!");
}

void Widget::dealGroupNotice(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    struct st_gNotice gnotice;
    gnotice.uid = obj["uid"].toInt();
    gnotice.gid = obj["gid"].toInt();
    gnotice.content = obj["content"].toString();
    gnotice.sendtime = obj["sendtime"].toString();

    QVariant var;
    var.setValue(gnotice);
    emit m_main->getMap_groupchatwindow()[gnotice.gid]->sig_addGroupNotice(var);
}

void Widget::dealNewGroupMember(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    int gid = obj["gid"].toInt();
    struct st_gMemberData gmemberdata;
    gmemberdata.mid = obj["uid"].toInt();
    gmemberdata.nick = obj["nick"].toString();

    QVariant var;
    var.setValue(gmemberdata);
    emit m_main->getMap_groupchatwindow()[gid]->sig_addGroupMember(var);

    m_main->getMap_groupchatwindow()[gid]->addNewGroupMemberRecord(gmemberdata);

}

void Widget::dealQuitGroupNotice(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    struct st_gMemberData gmember;
    gmember.mid= obj["uid"].toInt();
    int gid = obj["gid"].toInt();
    gmember.nick = obj["nick"].toString();

    QVariant var;
    var.setValue(gmember);
    // 从对应的群聊成员列表中删除该成员
    emit m_main->getMap_groupchatwindow()[gid]->sig_deleteGroupMember(var);

    m_main->getMap_groupchatwindow()[gid]->addGroupMemberQuitRecord(gmember);
}

void Widget::dealNewFriend(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    struct st_friendData fdata;
    fdata.dd_num = obj["dd_num"].toInt();
    fdata.nick = obj["nick"].toString();
    fdata.sex = obj["sex"].toString();
    fdata.phone = obj["phone"].toString();
    fdata.email = obj["email"].toString();
    fdata.city = obj["city"].toString();
    fdata.gxqm = obj["gxqm"].toString();
    fdata.birthday = obj["birthday"].toString();
    fdata.status = obj["status"].toInt();

    //同意则直接更新用户好友列表   好友链表
    GlobalObject::getGlobalObject()->insertFriendElement(fdata);
    //更新UI界面
    QVariant var;
    var.setValue(fdata);
    emit m_main->sign_addFriend(var);
}

void Widget::dealDeleteFriendReply(const QString &json)
{
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
    QJsonObject obj = doc.object();
    int fuid = obj["uid"].toInt();

    //从好友链表中删除好友
    GlobalObject::getGlobalObject()->deleteFriendFromList(fuid);
    //从TreeWidget中删除好友(更新界面)
    emit m_main->sign_deleteFriend(fuid);
}


void Widget::clearTmpFile()
{
    QString path = "../tmp";
    QDir dir(path);             // 初始化Dir为path路径
    dir.removeRecursively();    // 删除目录
    dir.setPath("../");         // 设置dir在当前路径
    dir.mkdir("./tmp");         // 创建目录
}

void Widget::dealReply(QString buf)
{
    //解析json响应报文,确定命令类型
    QString cmd = analysisJsonReply(buf.toUtf8());

    if(cmd == "login_reply")    //登录请求响应报文
        dealLoginReply(buf);
    else if(cmd == "get_user_info_reply")    //添加好友时的搜索结果
        dealGetUserInfoReply(buf);
    else if(cmd == "add_friend_reply")   //添加好友后的响应,比如已经是好友关系/等待对方处理
        dealAddFriendReply(buf);
    else if(cmd == "addfriend_request")  //处理其他用户发送的添加好友请求
        dealAddFriendRequest(buf);
    else if(cmd == "add_friend_result") //添加好友处理结果
        dealAddFriendResult(buf);
    else if(cmd == "friend_login")      //好友登录通知
        dealFriendLogin(buf);
    else if(cmd == "friend_quit")       //好友离线通知
        dealFriendQuit(buf);
    else if(cmd == "delete_friend_reply")   // 删除好友响应
        dealDeleteFriendReply(buf);
    else if(cmd == "deletefriend_notice")   //删除好友通知 (其他用户与你解除好友关系)
        dealDeleteFriendNotice(buf);
    else if(cmd == "new_push")      //推送通知,表示有新消息到达
        dealNewPush(buf);
    else if(cmd == "private_chat")  //私聊消息
        dealPrivateChat(buf);
    else if(cmd == "file_head_ack")     //文件头确认
        dealFileHeadACK(buf);
    else if(cmd == "upload_reply")  // 文件上传响应
        dealUpLoadReply(buf);
    else if(cmd == "create_group_reply")    // 创建群聊响应
        dealCreateGroupReply(buf);
    else if(cmd == "new_group_notice")  // 群创建通知
        dealNewGroupNotice(buf);
    else if(cmd == "dissolve_group_reply") // 解散群聊响应
        dealDissolveGroupReply(buf);
    else if(cmd == "get_group_info_reply") // 添加群聊时的搜索结果
        dealGetGroupInfoReply(buf);
    else if(cmd == "add_group_reply")   // 添加群聊响应
        dealAddGroupReply(buf);
    else if(cmd == "dissolve_group_notice") // 解散群聊通知
        dealDissolveGroupNotice(buf);
    else if(cmd == "quit_group_reply") // 退出群聊响应
        dealQuitGroupReply(buf);
    else if(cmd == "code_out_error")    // 验证码过期或不正确
        dealCodeOutError(buf);
    else if(cmd == "phone_already_register") // 手机号已被注册
        dealPhoneAlreadyRegister(buf);
    else if(cmd == "register_reply")    // 注册响应
        dealRegisterReply(buf);
    else if(cmd == "group_chat")    // 群聊信息
        dealGroupChat(buf);
    else if(cmd == "new_feed")  // 处理新动态通知
        dealNewFeed(buf);
    else if(cmd == "feed")      // 动态
        dealFeed(buf);
    else if(cmd == "new_dzpl")  // 点赞评论通知
        dealNewDZPL(buf);
    else if(cmd == "pl")        // 评论
        dealPL(buf);
    else if(cmd == "dz")        // 点赞
        dealDZ(buf);
    else if(cmd == "undz")      // 取消点赞
        dealUNDZ(buf);
    else if(cmd == "new_group_file")    // 新的群文件
        dealNewGroupFile(buf);
    else if(cmd == "file_srvpath")  // 文件下载
        dealFileSrvpath(buf);
    else if(cmd == "modify_user_info_reply")    // 编辑资料响应
        dealModifyUserInfoReply(buf);
    else if(cmd == "new_groupnotice")  // 新的群公告
        dealGroupNotice(buf);
    else if(cmd == "new_groupMember")   // 新群成员加入
        dealNewGroupMember(buf);
    else if(cmd == "quit_group_notice") // 群成员退出通知
        dealQuitGroupNotice(buf);
    else if(cmd == "new_friend")        // 新的好友
        dealNewFriend(buf);
}






